#include <functional>
#include <iostream>
#include <vector>
#include <memory>
#include <unordered_map>
#include <unistd.h>

using namespace std;

using TaskFunc = std::function<void()>;
using ReleaseFunc = std::function<void()>;
class TimeTask
{
private:
    uint64_t _id;      // 任务id，用来识别不同任务
    uint32_t _timeout; // 任务的超时时间
    TaskFunc _cb;      // 析构时任务所需要执行的回调函数
    ReleaseFunc _release;

public:
    TimeTask(uint64_t id, uint32_t timeout, const TaskFunc &cb)
        : _id(id), _timeout(timeout), _cb(cb)
    {
    }
    ~TimeTask()
    {
        _cb();
        _release();
    }
    void SetRelease(const ReleaseFunc &cb)
    {
        _release = cb;
    }

    uint32_t Delay_Time()
    {
        return _timeout;
    }
};

using PtrTask = std::shared_ptr<TimeTask>;
using WeakTask = std::weak_ptr<TimeTask>;
class TimerWheel
{
private:
    int _tick;                                // 秒针，走到哪，释放到哪
    int _capacity;                            // 该时间轮最大的延迟时间
    std::vector<std::vector<PtrTask>> _wheel; // 时间轮，用来记录任务
    std::unordered_map<uint64_t, WeakTask> _timers;
    
private:
    void Remove(uint64_t id) // 用来删除在_timers中记录的任务对象
    {
        auto it = _timers.find(id);
        if(it != _timers.end())
        {
            _timers.erase(it);
        }
    }

public:
    TimerWheel() : _tick(0), _capacity(60), _wheel(_capacity)//列表初始化是根据类成员的顺序决定的
    {
    }
    void TimerAdd(uint64_t id, uint32_t timeout, const TaskFunc &cb) // 添加任务到任务队列中去
    {
        PtrTask pt(new TimeTask(id, timeout, cb));
        pt->SetRelease(std::bind(&TimerWheel::Remove, this, id));//类内成员函数bind需要表明是哪个类成员函数
        int pos = (_tick + timeout) % _capacity;
        _wheel[pos].push_back(pt);
        _timers[id] = WeakTask(pt);
    }
    void TimerRefresh(uint64_t id) // 刷新对应的任务
    {
        auto it = _timers.find(id);
        if (it == _timers.end())
        {
            return;
        }
        PtrTask pt = it->second.lock();
        int timeout = pt->Delay_Time();
        int pos = (_tick + timeout) % _capacity;
        _wheel[pos].push_back(pt);
    }

    void RunTimerTask()
    {
        _tick = (_tick + 1) % _capacity;
        _wheel[_tick].clear();
    }
};

//测试代码
// class Test
// {
// public:
//     Test()
//     {
//         std::cout << "构造" << endl;
//     }
//     ~Test()
//     {
//         std::cout << "析构" << endl;
//     }
// };

// void DelTest(const Test *t)
// {
//     delete t;   
// }

// int main()
// {
//     TimerWheel tw;
//     Test *t = new Test();
//     // cout << "B" << endl;
//     tw.TimerAdd(555, 3, std::bind(DelTest, t));
//     // cout << "A" << endl;
//     for (int i = 0; i < 3; i++)
//     {
//         sleep(1);
//         tw.TimerRefresh(555);
//         tw.RunTimerTask();
//         cout << "aaaaaa" << endl;
//     }

//     while (1)
//     {
//         sleep(1);
//         cout << "-----------------\n";
//         tw.RunTimerTask();
//     }
//     return 0;
// }